package com.superboo.base.websocket.controller;

import com.superboo.base.websocket.domain.Message;
import com.superboo.base.websocket.domain.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SubscribeMapping;
import org.springframework.stereotype.Controller;

import java.security.Principal;

/**
 * WsController
 * 这个websocket是一个广播式的。
 * 这种基于stomp协议的实现.是基于请求回应的。只不过于request不同的是。这个可以是异步的。就是客户端请求后。
 * 可以做其他处理,而不用关心相应。
 * @author peiran zhang
 * @date 2017/4/7
 */
@Controller
public class WsController {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;//1



    //此处可以利用messagingTemplate 这个类主动给客户端推送消息。可以利用不同用户监听不同主题的方式。来实现点对点的推送。不过最好使用认证方式
    //当浏览器向服务端发送请求时,通过@MessageMapping映射到/welcome这个地址,类似于@RequestMapping
    @MessageMapping("/welcome")

    //当服务端有消息时,会对订阅了@SendTo中的路径的浏览器发送消息
    @SendTo("/topic/getResponse")
    public Response say(Message message) throws Exception {
        Thread.sleep(1000 * 3);
        return new Response("欢迎, " + message.getName() + "!");
    }



    //此处认证需要用到principal的实现。目前我已知的安全框架实现了这个接口的有
    //apache shiro 和 spring security所以这个例子没有能运行成功。
    @MessageMapping("/chat")
    public void handleChat(Principal principal, String msg) { //2
        System.out.println(principal.getName());
        messagingTemplate.convertAndSendToUser("wisely","/queue/notifications", principal.getName() + "-send:" + msg);
    }

    //在客户端订阅 /app/marco的时候自动调用。/app为配置中隐含的。
    //不经过代理
    //这个东西最重要的作用 其实就是实现一个一次性的。类似于请求回应的模式。只不过他和request的区别在于。这个是异步的。客户端不用等待阻塞。而且
    //这个消息不走代理所以很快哦。比如订单系统和产品页面在一个系统上。当时处理下单会很慢。同步请求会有等待。这个时候可以利用这个一次性的异步请求
    //回应。当然最好还是订单系统和网站分开。在利用webSocket stomp加消息中间件RabbitMQ、ActiveMQ和ZeroMQ - 等实现
    @SubscribeMapping({"/marco"})
    public Response handleSubscription() {
        return new Response("handleSubscription");
    }
}
